<?php
/**
 * Smart Library - Smart Framework
 * http://smart-framework.highet.eu
 *
 * @category   SmartL
 * @package    SmartL_Zend
 * @subpackage Controller
 * @copyright  Copyright (c) 2005-2008 Smart Framework team - Stepan Sindelar, Vojtech Vit
 * @license    http://www.opensource.org/licenses/bsd-license.php	New BSD License
 */

/**
 * @see SmartL_Zend_Controller_Router_UrlTable_DataAdapter_Interface
 */
require_once 'SmartL/Zend/Controller/Router/UrlTable/DataAdapter/Interface.php';

require_once 'Doctrine/Manager.php';

/**
 * Implementation of SmartL_Zend_Controller_Router_UrlTable_DataAdapter_Interface for Doctrine ORM.
 *
 * This class is not implemented yet.
 *
 * @package SmartL_Zend
 * @subpackage Controller
 */
class SmartL_Zend_Controller_Router_UrlTable_DataAdapter_Doctrine implements SmartL_Zend_Controller_Router_UrlTable_DataAdapter_Interface {
	const COLUMNS_CONFIG_URL = 'url';
	const COLUMNS_CONFIG_CONTROLLER = 'controller';
	const COLUMNS_CONFIG_ACTION = 'action';
	const COLUMNS_CONFIG_PARAM_NAME = 'paramName';
	const COLUMNS_CONFIG_PARAM_VALUE = 'paramValue';
	const COLUMNS_CONFIG_PARAM_URL_ID = 'paramUrlId';
	
	/**
	 * Name of class of record for main table of urls.
	 *
	 * @var string
	 */
	private $_recordName = 'smartl_urls';
	/**
	 * Name of class of record for one to many table with parametrs for urls.
	 *
	 * @var string
	 */
	private $_paramsRecordName = 'smartl_urls_params';
	/**
	 * Configuration (names) of columns in tables.
	 *
	 * @var array[string]=>string
	 */
	private $_columnsConfig = array (self::COLUMNS_CONFIG_URL => 'url', self::COLUMNS_CONFIG_CONTROLLER => 'controller', self::COLUMNS_CONFIG_ACTION => 'action', self::COLUMNS_CONFIG_PARAM_NAME => 'param_name', self::COLUMNS_CONFIG_PARAM_VALUE => 'value', self::COLUMNS_CONFIG_PARAM_URL_ID => 'url_id' );
	
	/**
	 * Cache of calling method urlExists.
	 * Index is string of url and value is boolean=result of this method for this string.
	 *
	 * @var array[string]=>boolean
	 */
	private $_urlExistsCache = array ();
	
	/**
	 * Cache of calling method requestExists.
	 * Index is md5 of concated strings in this order {controllerName}{actionName}{param1Name}{param1Value}
	 *
	 * @var array[string]=>boolean
	 */
	private $_requestExistsCache = array ();
	
	/**
	 * @var Doctrine_Manager
	 */
	private $_doctrineManager = null;
	
	/**
	 * Usage of config:
	 * 		under index 'recordName' may be name of class of record for main table.
	 * 		under index 'paramsRecordName' may be name of class of record for parameters table.
	 * 		undex index 'columnsCofig' may be configuration of names of columns in both tables.
	 *
	 * @param array $config
	 */
	public function __construct(array $config = array()) {
		if (isset ( $config ['recordName'] )) {
			$this->setRecordName ( $config ['recordName'] );
		}
		if (isset ( $config ['paramsRecordName'] )) {
			$this->setParamsRecordName ( $config ['paramsRecordName'] );
		}
		if (isset ( $config ['columnsConfig'] )) {
			$this->setColumnsConfig ( $config ['columnsConfig'] );
		}
		if (isset ( $config ['doctrineManager'] )) {
			//this is only for testing purposes
			$this->_doctrineManager = $config ['doctrineManager'];
		}
	}
	
	/**
	 * @param string $name
	 */
	public function setRecordName($name) {
		$this->_recordName = $name;
	}
	
	/**
	 * @return string
	 */
	public function getRecordName() {
		return $this->_recordName;
	}
	
	/**
	 * @param string $name
	 */
	public function setParamsRecordName($name) {
		$this->_paramsRecordName = $name;
	}
	
	/**
	 * @return string
	 */
	public function getParamsRecordName() {
		return $this->_paramsRecordName;
	}
	
	/**
	 * @return array
	 */
	public function getColumnsConfig() {
		return $this->_columnsConfig;
	}
	
	/**
	 * @param array $config
	 */
	public function setColumnsConfig(array $config) {
		$keys = array (self::COLUMNS_CONFIG_URL, self::COLUMNS_CONFIG_CONTROLLER, self::COLUMNS_CONFIG_ACTION, self::COLUMNS_CONFIG_PARAM_NAME, self::COLUMNS_CONFIG_PARAM_VALUE, self::COLUMNS_CONFIG_PARAM_URL_ID );
		
		foreach ( $keys as $key ) {
			if (! isset ( $config [$key] )) {
				require_once 'SmartL/Zend/Controller/Router/UrlTable/DataAdapter/Doctrine/Exception.php';
				throw new SmartL_Zend_Controller_Router_UrlTable_DataAdapter_Doctrine_Exception ( "Configuration for column {$key} in columns configuration missing." );
			}
		}
		
		$this->_columnsConfig = $config;
	}
	
	/**
	 * @return Doctrine_Manager
	 */
	protected function getDoctrineManager() {
		if ($this->_doctrineManager === null) {
			$this->_doctrineManager = Doctrine_Manager::getInstance ();
		}
		return $this->_doctrineManager;
	}
	
	//------------------------------------------------//
	//---------- implementation of interface ---------//
	

	/**
	 * Returns true if given url exists in data store.
	 *
	 * @param string $url
	 */
	public function urlExists($url) {
		throw new Exception ( "Not implemented" );
	}
	
	/**
	 * If given request exists, returns true.
	 *
	 * @param string $controller
	 * @param string $action
	 * @param array[string paramName]=>value $params
	 */
	public function requestExists($controller, $action, $params) {
		throw new Exception ( "Not implemented" );
	}
	
	/**
	 * Returns data of request assigned to given url.
	 *
	 * @param sring $url
	 * @return SmartL_Application_Config_RequestInfo
	 */
	public function getRequest($url) {
		throw new Exception ( "Not implemented" );
	}
	
	/**
	 * Returns url assigned to given request
	 *
	 * @param string $controller
	 * @param string $action
	 * @param array $params
	 */
	public function getUrl($controller, $action, $params) {
		throw new Exception ( "Not implemented" );
	}
	
	/**
	 * Adds url to data storage.
	 *
	 * @param string $url
	 * @param string $controller
	 * @param string $action
	 * @param array[string]=>string $params
	 * @throws SmartL_Zend_Controller_Router_UrlTable_DataAdapter_{ClassName}_Exception
	 * When the given url of request exists.
	 */
	public function addUrl($url, $controller, $action, $params) {
		throw new Exception ( "Not implemented" );
	}
	
	/**
	 * Remove given url data from data store.
	 *
	 * @param string $url
	 */
	public function removeUrl($url) {
		throw new Exception ( "Not implemented" );
	}
}